package com.xyz.aclservice.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.xyz.aclservice.entity.EduUser;
import com.xyz.aclservice.entity.EduPermission;
import com.xyz.aclservice.entity.EduRolePermission;
import com.xyz.aclservice.helper.MemuHelper;
import com.xyz.aclservice.helper.PermissionHelper;
import com.xyz.dao.EduPermissionMapper;
import com.xyz.aclservice.service.EduPermissionService;
import com.xyz.aclservice.service.EduRolePermissionService;
import com.xyz.aclservice.service.EduUserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 权限 服务实现类
 * </p>
 *
 * @author testjava
 * @since 2020-01-12
 */
@Service
public class EduPermissionServiceImpl extends ServiceImpl<EduPermissionMapper, EduPermission> implements EduPermissionService {

    @Autowired
    private EduRolePermissionService eduRolePermissionService;

    @Autowired
    private EduUserService eduUserService;

    //获取全部菜单
    @Override
    public List<EduPermission> queryAllMenu() {

        QueryWrapper<EduPermission> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("id");
        List<EduPermission> eduPermissionList = baseMapper.selectList(wrapper);

        List<EduPermission> result = bulid(eduPermissionList);

        return result;
    }

    //根据角色获取菜单
    @Override
    public List<EduPermission> selectAllMenu(String roleId) {
        List<EduPermission> allEduPermissionList = baseMapper.selectList(new QueryWrapper<EduPermission>().orderByAsc("CAST(id AS SIGNED)"));

        //根据角色id获取角色权限
        List<EduRolePermission> eduRolePermissionList = eduRolePermissionService.list(new QueryWrapper<EduRolePermission>().eq("role_id", roleId));
        //转换给角色id与角色权限对应Map对象
//        List<String> permissionIdList = rolePermissionList.stream().map(e -> e.getPermissionId()).collect(Collectors.toList());
//        allPermissionList.forEach(permission -> {
//            if(permissionIdList.contains(permission.getId())) {
//                permission.setSelect(true);
//            } else {
//                permission.setSelect(false);
//            }
//        });
        for (int i = 0; i < allEduPermissionList.size(); i++) {
            EduPermission eduPermission = allEduPermissionList.get(i);
            for (int m = 0; m < eduRolePermissionList.size(); m++) {
                EduRolePermission eduRolePermission = eduRolePermissionList.get(m);
                if (eduRolePermission.getPermissionId().equals(eduPermission.getId())) {
                    eduPermission.setSelect(true);
                }
            }
        }


        List<EduPermission> eduPermissionList = bulid(allEduPermissionList);
        return eduPermissionList;
    }

    //给角色分配权限
    @Override
    public void saveRolePermissionRealtionShip(String roleId, String[] permissionIds) {

        eduRolePermissionService.remove(new QueryWrapper<EduRolePermission>().eq("role_id", roleId));


        List<EduRolePermission> eduRolePermissionList = new ArrayList<>();
        for (String permissionId : permissionIds) {
            if (StringUtils.isEmpty(permissionId)) continue;

            EduRolePermission eduRolePermission = new EduRolePermission();
            eduRolePermission.setRoleId(roleId);
            eduRolePermission.setPermissionId(permissionId);
            eduRolePermissionList.add(eduRolePermission);
        }
        //acl_role_permission手动添加一条
        EduRolePermission specialPer = new EduRolePermission();
        specialPer.setRoleId(roleId);
        specialPer.setPermissionId("1");
        eduRolePermissionList.add(specialPer);

        eduRolePermissionService.saveBatch(eduRolePermissionList);
    }

    //递归删除菜单
    @Override
    public void removeChildById(String id) {
        List<String> idList = new ArrayList<>();
        this.selectChildListById(id, idList);

        idList.add(id);
        baseMapper.deleteBatchIds(idList);
    }

    //根据用户id获取用户菜单
    @Override
    public List<String> selectPermissionValueByUserId(String id) {

        List<String> selectPermissionValueList = null;
        if (this.isSysAdmin(id)) {
            //如果是系统管理员，获取所有权限
            selectPermissionValueList = baseMapper.selectAllPermissionValue();
        } else {
            selectPermissionValueList = baseMapper.selectPermissionValueByUserId(id);
        }
        return selectPermissionValueList;
    }

    @Override
    public List<JSONObject> selectPermissionByUserId(String userId) {
        List<EduPermission> selectEduPermissionList = null;
        if (this.isSysAdmin(userId)) {
            //如果是超级管理员，获取所有菜单
            selectEduPermissionList = baseMapper.selectList(null);
        } else {
            selectEduPermissionList = baseMapper.selectPermissionByUserId(userId);
        }
        List<EduPermission> eduPermissionList = PermissionHelper.bulid(selectEduPermissionList);
        List<JSONObject> result = MemuHelper.bulid(eduPermissionList);
        return result;
    }

    /**
     * 判断用户是否系统管理员
     *
     * @param userId
     * @return
     */
    private boolean isSysAdmin(String userId) {
        EduUser eduUser = eduUserService.getById(userId);

        if (null != eduUser && "admin".equals(eduUser.getUsername())) {
            return true;
        }
        return false;
    }

    /**
     * 递归获取子节点
     *
     * @param id
     * @param idList
     */
    private void selectChildListById(String id, List<String> idList) {
        List<EduPermission> childList = baseMapper.selectList(new QueryWrapper<EduPermission>().eq("pid", id).select("id"));
        childList.stream().forEach(item -> {
            idList.add(item.getId());
            this.selectChildListById(item.getId(), idList);
        });
    }

    /**
     * 使用递归方法建菜单
     *
     * @param treeNodes
     * @return
     */
    private static List<EduPermission> bulid(List<EduPermission> treeNodes) {
        List<EduPermission> trees = new ArrayList<>();
        for (EduPermission treeNode : treeNodes) {
            if ("0".equals(treeNode.getPid())) {
                treeNode.setLevel(1);
                trees.add(findChildren(treeNode, treeNodes));
            }
        }
        return trees;
    }

    /**
     * 递归查找子节点
     *
     * @param treeNodes
     * @return
     */
    private static EduPermission findChildren(EduPermission treeNode, List<EduPermission> treeNodes) {
        treeNode.setChildren(new ArrayList<EduPermission>());

        for (EduPermission it : treeNodes) {
            if (treeNode.getId().equals(it.getPid())) {
                int level = treeNode.getLevel() + 1;
                it.setLevel(level);
                if (treeNode.getChildren() == null) {
                    treeNode.setChildren(new ArrayList<>());
                }
                treeNode.getChildren().add(findChildren(it, treeNodes));
            }
        }
        return treeNode;
    }


    //把返回所有菜单list集合进行封装的方法
    public static List<EduPermission> bulidPermission(List<EduPermission> eduPermissionList) {

        //创建list集合，用于数据最终封装
        List<EduPermission> finalNode = new ArrayList<>();
        //把所有菜单list集合遍历，得到顶层菜单 pid=0菜单，设置level是1
        for (EduPermission eduPermissionNode : eduPermissionList) {
            //得到顶层菜单 pid=0菜单
            if ("0".equals(eduPermissionNode.getPid())) {
                //设置顶层菜单的level是1
                eduPermissionNode.setLevel(1);
                //根据顶层菜单，向里面进行查询子菜单，封装到finalNode里面
                finalNode.add(selectChildren(eduPermissionNode, eduPermissionList));
            }
        }
        return finalNode;
    }

    private static EduPermission selectChildren(EduPermission eduPermissionNode, List<EduPermission> eduPermissionList) {
        //1 因为向一层菜单里面放二层菜单，二层里面还要放三层，把对象初始化
        eduPermissionNode.setChildren(new ArrayList<EduPermission>());

        //2 遍历所有菜单list集合，进行判断比较，比较id和pid值是否相同
        for (EduPermission it : eduPermissionList) {
            //判断 id和pid值是否相同
            if (eduPermissionNode.getId().equals(it.getPid())) {
                //把父菜单的level值+1
                int level = eduPermissionNode.getLevel() + 1;
                it.setLevel(level);
                //如果children为空，进行初始化操作
                if (eduPermissionNode.getChildren() == null) {
                    eduPermissionNode.setChildren(new ArrayList<EduPermission>());
                }
                //把查询出来的子菜单放到父菜单里面
                eduPermissionNode.getChildren().add(selectChildren(it, eduPermissionList));
            }
        }
        return eduPermissionNode;
    }

    //2 根据当前菜单id，查询菜单里面子菜单id，封装到list集合
    private void selectPermissionChildById(String id, List<String> idList) {
        //查询菜单里面子菜单id
        QueryWrapper<EduPermission> wrapper = new QueryWrapper<>();
        wrapper.eq("pid", id);
        wrapper.select("id");
        List<EduPermission> childIdList = baseMapper.selectList(wrapper);
        //把childIdList里面菜单id值获取出来，封装idList里面，做递归查询
        childIdList.stream().forEach(item -> {
            //封装idList里面
            idList.add(item.getId());
            //递归查询
            this.selectPermissionChildById(item.getId(), idList);
        });
    }

}
